package com.springcloud.auth.config;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.springcloud.auth.entity.TToken;
import com.springcloud.auth.service.TTokenService;
import com.springcloud.commom.utils.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;


/**
 * 继承Application接口后项目启动时会按照执行顺序执行run方法
 * 通过设置Order的value来指定执行的顺序
 */
@Component
@Order(value = 100)
public class StartService implements ApplicationRunner {

    private static final Logger logger = LoggerFactory.getLogger(StartService.class);

    @Autowired
    private RedisUtil redis;

    @Autowired
    private TTokenService service;

    /*
     *
     * 启动重新装载凭证到redis 里面，防止redis宕机而发生数据丢失
     * @see org.springframework.boot.ApplicationRunner#run(org.springframework.boot.ApplicationArguments)
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        logger.info("================StartService================begin==============");
        //取出数据库里面未过期的token
        QueryWrapper<TToken> queryWrapper = new QueryWrapper<>();

        Date now = new Date();

        //倒退 access 刷新的时间
        long accessTimes = now.getTime() - (OauthConfig.ACCESS_TOKEN_EXPIRE * 1000);

        Date expireDate = DateUtil.offsetMinute(new Date(),30);

        //符合装入的时间,   now   <= 时间 <= now + 30 分钟
        queryWrapper.lambda().le(TToken::getRefreshUpdateTime, expireDate);
        queryWrapper.lambda().ge(TToken::getRefreshUpdateTime, now);

        List<TToken> list = service.list(queryWrapper);

        //把凭证装入redis
        for (TToken token : list) {

            // 加入accessToken
            if (token.getAccessUpdateTime().getTime() > accessTimes) {
                //计算时间差
                int timeout = (int) (token.getAccessUpdateTime().getTime() + (OauthConfig.ACCESS_TOKEN_EXPIRE * 1000) - now.getTime()) / 1000;
                logger.info("accessToken:" + token.getAccessToken());
                logger.info("acess  timeout:" + timeout);
                if (timeout != 0) {
                    redis.set(OauthConfig.AUTH_ACCESS_TOKEN + token.getAccessToken(), token.getToken(), timeout);
                }
            }

            // 加入refreshToken
            //计算时间差
            int timeout = (int) (token.getRefreshUpdateTime().getTime() + (OauthConfig.REFRESH_TOKEN_EXPIRE * 1000) - now.getTime()) / 1000;
            logger.info("refreshToken:" + token.getRefreshToken());
            logger.info("refresh  timeout:" + timeout);
            if (timeout != 0) {
                redis.set(OauthConfig.AUTH_REFRESH_TOKEN + token.getRefreshToken(), token.getToken(), timeout);
            }
        }

        //删除过期的token
        QueryWrapper<TToken> qw = new QueryWrapper<>();

        //获取refreshTime无效时间,即 refreshTime < now() - 30分钟
        qw.lambda().lt(TToken::getRefreshUpdateTime, DateUtil.offsetMinute(new Date(),-30));

        List<TToken> list2 = service.list(qw);
        for(TToken token : list2){
            service.removeById(token.getId());
        }

        logger.info("================StartService================end==============");
    }

}